/*
 * comlan
 */

package com.promfy.timetable.ui;


import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.promfy.timetable.R;
import com.promfy.timetable.db.OneClassDBService;
import com.promfy.timetable.db.ReminderDBService;
import com.promfy.timetable.domain.OneClass;
import com.promfy.timetable.domain.Reminders;
import com.promfy.util.DateFormatUtil;

public class TimetableView extends LinearLayout implements OnClickListener,OnTouchListener{
	private final static int FRESH_TIME = 0;

	private static final String TAG = "p_tv";
	
	private Handler handler = new Handler(){

		@Override
		public void handleMessage(Message msg) {
			int what = msg.what;
			switch (what) {
			case FRESH_TIME:
				title.setText(DateFormatUtil.getTitle());
				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
		
	};
	
	private LayoutInflater inflater;
	private Context context; 
	private View view;
	private LinearLayout tableLayout;
	
	private long courseWidth;
	private long courseHeight;
	private long edgeWidth;
	private int titleHight = 130;

	private TextView title;

	private Button btn;

	private Map<Integer,View> weekViewMap = new HashMap<Integer, View>();
	private Map<Integer,View> nightViewMap = new HashMap<Integer, View>();
	List<OneClass> oneClassList;

	public long getCourseWidth() {
		return courseWidth;
	}

 
	public void setCourseWidth(long courseWidth) {
		this.courseWidth = courseWidth;
	}


	public long getCourseHeight() {
		return courseHeight;
	}


	public void setCourseHeight(long courseHeight) {
		this.courseHeight = courseHeight;
	}


	public long getEdgeWidth() {
		return edgeWidth;
	}


	public void setEdgeWidth(long edgeWidth) {
		this.edgeWidth = edgeWidth;
	}


	public TimetableView(Context context){//, int width, int height,long courseWidth, long courseHeight, long edgeWidth) {
		super(context);
		this.context = context;
	
		screenWidth = (int)(((Activity) getContext()).getWindowManager().getDefaultDisplay().getWidth() );
		screenHeight = (int)(((Activity) getContext()).getWindowManager().getDefaultDisplay().getHeight() );

		courseWidth = screenWidth / 5;
		edgeWidth = courseWidth/2;
		courseHeight = (screenHeight - titleHight)  / 6;
		
		initView();
		initData();
		
	}

	
	public TimetableView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}



	private void initView(){
		inflater = LayoutInflater.from(context);
		view = inflater.inflate(R.layout.timetable, this);
		tableLayout = (LinearLayout)view.findViewById(R.id.table_main);
		title = (TextView)findViewById(R.id.title_timetable);
		//view.setOnTouchListener(this);
//		Button btn = new Button(context);
//		tableLayout.addView(btn,new LayoutParams((int)edgeWidth,(int)courseHeight));
//		btn.setOnTouchListener(this); 
	}
	
	private void initData() {
		title.setText(DateFormatUtil.getTitle());
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true){
					handler.sendEmptyMessage(FRESH_TIME);
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}).start();
		//make class  
		// get list
		OneClassDBService ocdb = new OneClassDBService(context);
		try {
			oneClassList = ocdb.getList();
			weekViewMap.clear();
			nightViewMap.clear();
			for(int i = 0; i<6; i++){
				LinearLayout ll = new LinearLayout(context);
				ll.setOrientation(HORIZONTAL);
				TextView tv = new TextView(context);
				tv.setText(mapToWeek(i+1));
				tv.setTextColor(Color.WHITE);
				tv.setGravity(Gravity.CENTER);
				//setViewBg(i, tv);
				ll.addView(tv, new LayoutParams((int)edgeWidth,(int)courseHeight));
				weekViewMap.put(i+1,tv);
				
				for(OneClass oneClass : oneClassList){
					if(oneClass.getWeek() != i+1) continue;
					switch(oneClass.getCourse()){ 
					case 1: 
						OneClassView ocv1 = new OneClassView(context,oneClass);
						ocv1.setOnTouchListener(this);
						//setViewBg(i, ocv1.getLinear());
						ll.addView(ocv1, new LayoutParams((int)courseWidth,(int)courseHeight));
						break;
					case 3:
						OneClassView ocv3 = new OneClassView(context,oneClass);
						ocv3.setOnTouchListener(this);
						//setViewBg(i, ocv3.getLinear());
						ll.addView(ocv3, new LayoutParams((int)courseWidth,(int)courseHeight));
						break;
					case 5:
						OneClassView ocv5 = new OneClassView(context,oneClass);
						ocv5.setOnTouchListener(this);
						//setViewBg(i, ocv5.getLinear());
						ll.addView(ocv5, new LayoutParams((int)courseWidth,(int)courseHeight));
						break;
					case 7:
						OneClassView ocv7 = new OneClassView(context,oneClass);
						ocv7.setOnTouchListener(this);
						//setViewBg(i, ocv7.getLinear());
						ll.addView(ocv7, new LayoutParams((int)courseWidth,(int)courseHeight));
						break; 
//					case 9: 
//						OneClassView ocv9 = new OneClassView(context);
//						ocv9.setOnTouchListener(this);
//						ll.addView(ocv9, new LayoutParams((int)edgeWidth,(int)courseHeight));
//						break;
					}
				} 
				TextView tv1 = new TextView(context);
 				tv1.setTextColor(Color.WHITE);
				tv1.setGravity(Gravity.CENTER);
				//setViewBg(i, tv1);
				ll.addView(tv1, new LayoutParams((int)edgeWidth,(int)courseHeight));
				nightViewMap.put(i+1, tv1);
				tableLayout.addView(ll, new LayoutParams((int)screenWidth,(int)courseHeight));
			}
		} catch (Exception e) { 
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		btn = new Button(context);
		btn.setOnTouchListener(this);
		tableLayout.addView(btn, new LayoutParams((int)courseWidth,(int)courseHeight));
	}
	 
	private void setViewBg(int i, View v){
		if(i%2 == 0){
			v.setBackgroundColor(Color.BLACK);
		}else{
			v.setBackgroundColor(Color.DKGRAY);
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		//restart
		case 1:
		
			break;
		//back to mode
		case 2:

			break;
		//exit
		case 3:
			
			break;
		default:
			break;
		}
	}

	private int screenHeight;
	private int screenWidth;
	
	private int screenOffsetLeft = 0;
	private int screenOffsetRight = 0;
	private int screenOffsetTop = 0;
	private int screenOffsetBottom = 0;
	
	private int lastX;
	private int lastY;

	private int moveX;
	private int moveY;

	private int left;
	private int top;
	private int right;
	private int bottom;

	private OneClass downOneClass;
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		super.onTouchEvent(event);
		int ea = event.getAction();
		switch (ea) {
		case MotionEvent.ACTION_DOWN:
			v.setBackgroundColor(Color.BLUE);
			lastX = (int) event.getRawX();
			lastY = (int) event.getRawX();
			if(v.getClass().equals(OneClassView.class)){
				downOneClass = ((OneClassView)v).getOneClass();
			}
			break;
		/**
		 * layout(l,t,r,b) l Left position, relative to parent t Top position,
		 * relative to parent r Right position, relative to parent b Bottom
		 * position, relative to parent
		 * */
		case MotionEvent.ACTION_MOVE:
			moveX = (int) event.getRawX();
			moveY = (int) event.getRawY();
		
			//Log.d(TAG, "moveX:" + moveX + "   moveY:" + moveY);
			int dx = moveX - lastX;
			int dy = moveY - lastY; 
			if(dx < 3 && dx > -3) dx = 0;
			if(dy < 3 && dy > -3) dy = 0;
			
//			left = v.getLeft() + dx;
//			top = v.getTop() + dy;
//			right = v.getRight() + dx;
//			bottom = v.getBottom() + dy;
			left = (int) (moveX - courseWidth/2);
			top = (int) (moveY - courseHeight/2)-titleHight;
			right = (int) (moveX + courseWidth/2);
			bottom = (int) (moveY + courseHeight/2)-titleHight;

			if (left < 0 + screenOffsetLeft) {  
				left = 0 + screenOffsetLeft;
				right = left + v.getWidth();
			}

			if (right > screenWidth - screenOffsetRight) {
				right = screenWidth - screenOffsetRight;
				left = right - v.getWidth();
			}

			if (top < 0 + screenOffsetTop) {
				top = 0 + screenOffsetTop;
				bottom = top + v.getHeight();
			}

			if (bottom > screenHeight - screenOffsetBottom) {
				bottom = screenHeight - screenOffsetBottom;
				top = bottom - v.getHeight();
			}
			Log.d(TAG, "[" + left + ", " + top +", " + right + ", " + bottom + "]");
			btn.layout(left, top, right, bottom); 
			if(btn.getVisibility() != VISIBLE) btn.setVisibility(VISIBLE);
			inSomeReminderRect(moveX,moveY);
			break;
		case MotionEvent.ACTION_UP:
			btn.setVisibility(INVISIBLE);
			v.setBackgroundColor(Color.BLACK);
			intelRecord(moveX,moveY);
			recoverReminderRect();
			downOneClass = null;
			break;
		}
		return true;
	}
	
	private void recoverReminderRect() {
		Iterator<Integer> weekIter = weekViewMap.keySet().iterator();
		while(weekIter.hasNext()){
			View v = weekViewMap.get(weekIter.next());
			v.setBackgroundColor(Color.BLACK);
		}
		
		Iterator<Integer> nightIter = nightViewMap.keySet().iterator();
		while(nightIter.hasNext()){
			View v = nightViewMap.get(nightIter.next());
			v.setBackgroundColor(Color.BLACK);
		}
		
	}


	/**
	 * if touch point in some reminders-rect, set background
	 */
	private void inSomeReminderRect(int x, int y) {
		// TODO Auto-generated method stub
		y = y-titleHight;
		int w = (int) (y/courseHeight + 1);
		recoverReminderRect();
		if(x >= 0 && x <= edgeWidth){
			weekViewMap.get(w).setBackgroundColor(Color.RED);
		}else if (x >= screenWidth - edgeWidth && x <= screenWidth){
			nightViewMap.get(w).setBackgroundColor(Color.GREEN);
		}
	}


	/**
	 * intellengent record reminders
	 * @param w
	 */
	private void intelRecord(int x, int y) {
		if(downOneClass == null) return;
		int downWeek = downOneClass.getWeek();
		y = y-titleHight;
		int w = (int) (y/courseHeight + 1);
		recoverReminderRect();
		Reminders reminder ;
		String intelContent = null ;
		int today = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
		if(x >= 0 && x <= edgeWidth){
			if(downWeek >= w){
				intelContent = "请准备于周 "+mapToWeek(w)+"交上周" + mapToWeek(downWeek) + "的作业(" + downOneClass.getClassName() + ")";
			}else{
				intelContent = "请准备于周 "+mapToWeek(w)+"交周" + mapToWeek(downWeek) + "的作业(" + downOneClass.getClassName() + ")";				
			}
		}else if (x >= screenWidth - edgeWidth && x <= screenWidth){
			
			if (w >= downWeek && w - downWeek <= 2) {
				intelContent = "请于周" + mapToWeek(w) + "复习周"+ mapToWeek(downWeek) + "课程("+ downOneClass.getClassName() + ")";
			} else if (w > downWeek && w - downWeek > 2) {
				intelContent = "请于周" + mapToWeek(w) + "预习下周"+ mapToWeek(downWeek) + "的课程("+ downOneClass.getClassName() + ")";
			} else if (w < downWeek && downWeek - w > 2) {
				intelContent = "请于周" + mapToWeek(w) + "复习上周"+ mapToWeek(downWeek) + "的课程("+ downOneClass.getClassName() + ")";
			} else if (w < downWeek && downWeek - w <= 2) {
				intelContent = "请于周" + mapToWeek(w) + "预习周"+ mapToWeek(downWeek) + "的课程("+ downOneClass.getClassName() + ")";
			}
		}
		
		
		if(intelContent == null) return;
		reminder = new Reminders(System.currentTimeMillis(), intelContent, Reminders.REMINDERS_STATUS_INIT);				
		ReminderDBService rds = new ReminderDBService(context);
		try {
			rds.insert(reminder);
			Toast.makeText(context, "课程" + downOneClass.getClassName() + "已添加!", Toast.LENGTH_SHORT).show();
		} catch (Exception e) {
			// TODO Auto-ge nerated catch block 
			e.printStackTrace();
		}
		
	}


	/**
	 * get which day of week you want to add course to reminders.
	 * @param y
	 * @return
	 */
	private int getTouchUpWeek(float y){
		return (int) ((y - titleHight)/courseHeight + 1);
	}
	
	private String mapToWeek(int week){
		switch(week){
		case 1:
			return  "一";
		case 2:
			return  "二";
		case 3:
			return  "三";
		case 4:
			return  "四";
		case 5:
			return  "五";
		case 6:
		case 7:
			return  "末";
		default:
			return "";
		}
	}

}
